#!/usr/bin/perl
#shareman-lib.pl

do "../web-lib.pl";
&init_config();
%access = get_module_acl();

#------------below changed by chenmo for user samba config file---#
sub write_user_conf
{
    my $curruser = $_[0];
    my $currconf = "/sysvol/etc/samba/smb.conf.".$curruser;
    open(SC, "/etc/samba/smb.conf");
    @smbconf = <SC>;
    close(SC);
    open(UC, "> $currconf");
    for($i=0; $i<@smbconf; $i++)
    { 
      $mark = 0;
      if($smbconf[$i] =~ /^\s+valid\susers\s*\S\s*(.*)\n/){
         @tmpline = split(/,/, $1);
         $mark = is_user_valid($curruser, @tmpline);
      }

      if($smbconf[$i] =~ /^\s+invalid\susers\s*\S\s*(.*)\n/)
      {  
         @tmpline = split(/,/, $1);
         $mark = is_user_invalid($curruser, @tmpline); 
      }

      print UC $smbconf[$i];

      if($mark) 
      {
         print UC "	browseable = no\n";
      }
    } 
    close(UC);    
      
}
sub get_localuser
{
    open(LOCALUSER, $config{'localuser_file'});
    @file = <LOCALUSER>;
    close(LOCALUSER);

    for($i = @file - 1; $i >= 0; $i--)
    {
        chomp($file[$i]);
        $file[$i] =~ s/#.*$//;
        @line = split(':', $file[$i]);
        if($line[0])
        {
           $file[$i] = $line[0];
        }
        else
        {
           splice @file, $i, 1;
        }
    }
    
    @file = sort {$a cmp $b} @file;	  
    return @file; 
}
sub is_user_valid
{
   $result = 1;
   my ($vauu, @valist) = @_;
   @valid_lists = get_userlists(@valist);
   foreach $val (@valid_lists)
   {
      if($val eq $vauu)
      {
         $result = 0;
         last;
      }
   }
   return $result;
}
sub is_user_invalid
{
   $result = 0;
   my ($uu, @invalist) = @_;
   @invalid_lists = get_userlists(@invalist);
   foreach $inv (@invalid_lists)
   {
       if($inv eq $uu)
       {
          $result = 1;
          last;
       }
   }
   return $result; 
}
sub get_userlists
{
#  param1 is the valid or invalid lists, such as(@cm, cm1, cm2..)
   my (@aaa) = @_;
   my @share_userlists = ();
   foreach $ul (@aaa)
   {
       if($ul =~ /^@(\S+)/){
          $gname = $1;
          open(GP, "/etc/group");
          @group = <GP>;
          close(GP);
          foreach $grp (@group)
          {
             $grp =~ /(.*)\n/;
             $grp = $1;
             @tmpstr = split(/:/, $grp);
             if($tmpstr[0] eq $gname){
                @gpusers = split(/,/, $tmpstr[3]);
                foreach $gu (@gpusers){
                   push(@share_userlists, $gu);
                }
             }
          }
       }
       else{
           push(@share_userlists, $ul);
       }
   }
#   foreach $su (@share_userlists){
#       `echo $su >> /root/valuu`;
#   }
   return @share_userlists;

}

#-----------above changed by chenmo for user samba config file----#
#the 2nd parameter: 1--key is sharename; 2--key is sharepath
sub read_sharetab
{
	local $a = $_[0];
	local $k = $_[1];
	open(SHARETAB, $config{'sharetab_file'});
	while($line = <SHARETAB>)
	{
		$line =~ s/\r|\n//g;
		$line =~ s/#.*$//g;
		$line =~ s/\/\/.*$//g;

		if ($line)
		{
			while($line=~ /\\$/)
			{
				local $nl = <SHARETAB>;
				$line =~ s/\\$//;
				$nl =~ s/^\s+//;
				$line.=$nl;
			}
			local ($path, $sharename, $sharetype, $comment) = split(/:/, $line);
			$a->{$sharename} = {sharepath => $path, sharetype => $sharetype, comment => $comment} if ($k ==1);
			$a->{$path} = {sharename => $sharename, sharetype => $sharetype, comment => $comment} if ($k ==2);
		}

	}
	close(SHARETAB);
}

sub list_shares
{
	#print "<form name=sharesform>\n";
	print "<table width=100% class=mode2><tr>\n";
	print "<td  valign=top><div class=main><table  class=mode1 border=0 bordercolor=#33ccff cellspacing=0 cellpadding=1 width=100%>\n";
	print "<tr class=title1> <th align=left>$text{'sharename'}</th> ",
		"<th align=left>$text{'sharepath'}</th> ",
		"<th align=left>$text{'sharetype'}</th> ",
		"<th align=left>$text{'comment'}</th> </tr>\n";
	my $i = 0;
	my %sharefile;
	&read_sharetab(\%sharefile, 1);
	foreach $key (sort {$a cmp $b} keys(%sharefile)) {
		#print "<tr $cb>\n";
		$i++;
		#print "<tr $cb>\n";
		if ($i % 2 eq 0)
		{
			$dismode = "class=mode2";

		}
		else
		{
			$dismode = "class=mode1";

		}
		print "<tr $dismode>\n";
		print "<td width=25%><input type=radio name=sharedir value='$sharefile{$key}{'sharepath'}'><img border=0 src=images/share.gif>$key</td>\n";
		printf "<td nowarp $dismode width=25%>%s$sharefile{$key}{'sharepath'}%s</td>\n", (-e $sharefile{$key}{'sharepath'})?"":"<strike>", (-e $sharefile{$key}{'sharepath'})?"":"</strike>";
		my $stype;
		$stype .='W ' if ($sharefile{$key}{'sharetype'} =~ /W/);
		$stype .='U ' if ($sharefile{$key}{'sharetype'} =~ /U/);
		$stype .='F ' if ($sharefile{$key}{'sharetype'} =~ /F/);
		$stype .='H ' if ($sharefile{$key}{'sharetype'} =~ /H/);
		$stype .='A ' if ($sharefile{$key}{'sharetype'} =~ /A/);
		print "<td nowarp width=15%>$stype</td>\n";
		printf "<td nowarp $dismode>%s</td> </tr>\n", ($sharefile{$key}{'comment'})?$sharefile{$key}{'comment'}:$text{'none'};

	}
	print "</table></div></td>\n";
	#print "</form>\n";
	my $n = keys(%sharefile);
	print "<td valign=top width=160><table class=mode1 border=0 cellspacing=8 cellpadding=1 width=100%>\n";
	print "<tr><td align=center><input type=submit name=newshare value=\"$text{'create_share'}\" onclick='return SetEditValue(this, $n)' class=button></td></tr>\n";
#	if ($n)
#	{
	printf "<tr><td align=center><input type=submit %s name=delshare value=\"$text{'delete_share'}\" onclick='return SetEditValue(this, $n)' class=button></td></tr>\n", ($n)?"":"disabled=true";
	printf "<tr><td align=center><input type=submit %s name=editshare value=\"$text{'edit_share'}\" onclick='return SetEditValue(this, $n)' class=button></td></tr>\n", ($n)?"":"disabled=true";
#	}
	print "</table></td></tr>\n";
	print "<tr><td colspan=2><i>$text{'sharetypes_hint'}</i></td></tr>\n";
	print "</table>\n";

	return $n;

}

sub search_shareinfo
{
	my @ret = ();
	open(SHARETAB, $config{'sharetab_file'});
	while($line = <SHARETAB>)
	{
		$line =~ s/#.*$//g;
		$line =~ s/\/\/.*$//g;
		chomp($line);

		if ($line)
		{
			while($line=~ /\\$/)
			{
				local $nl = <SHARETAB>;
				$line =~ s/\\$//;
				$nl =~ s/^\s+//;
				$line.=$nl;
			}
			local ($path, $sharename, $sharetype, $comment) = split(/:/, $line);
			if ($_[0] eq $path)
			{
				push(@ret, $sharename);
				push(@ret, $sharetype);
				push(@ret, $comment);
				break;
			}
		}
	}
	close(SHARETAB);
	return @ret;
}

#1st param means oper type:1--add;2--del;3--replace
#when param1=1 or 3,the next params are sharepath,sharename,sharetype,comment
#when param1=2,the next param is sharepath
sub save_sharetab
{

	&lock_file($config{'sharetab_file'});
	$file = &read_file_lines($config{'sharetab_file'});
	$number = -1;
	my $found = false;
	for($i=0; $i<@$file; $i++)
	{
    		$line = $file->[$i];
    		$line =~ s/\r|\n//g;
    		$line =~ s/#.*$//g;
    		$line =~ s/\/\/.*$//g;

    		if( $line )
    		{
			local $si = $i;

			while($line =~ /\\$/)
			{
				local $nl = $file->[++$i];
				$line =~ s/\\$//;
				$nl =~ s/^\s+//;
				$line .= $nl;
			}

        		local ( $path, $name, $stype, $comment ) = split( /:/, $line );
			if ($path eq $_[1])
			{
				$number = $si;
				$enumber = $i;
				$found = true;
			}

			if (($_[0] == 1) && ($path eq $_[1]))
			{
				&error( &text('sharepath_already_tab', $path) );
			}

			if (($_[0] == 1) && ($name eq $_[2]))
			{
				&error( &text('sharename_already_tab', $name) );
			}

    		}
	}
	if ((($_[0] == 2) ||($_[0] == 3)) && !$found)
	{
		&error($text{'sharepath_notexist_tab'});
	}
	if( $_[0] == 2 )
	{
   		splice( @$file, $number, $enumber-$number+1 );
	}
	elsif (($_[0] == 3)&&$found )
	{
		local $new = $_[1]. ":";
		$new .= $_[2]. ":". $_[3]. ":". $_[4];
		splice( @$file, $number, $enumber-$number+1, $new);

	}
	else
	{
		local $new1 = $_[1]. ":";
		$new1 .= $_[2]. ":". $_[3]. ":". $_[4];
		push( @$file, $new1 );
	}
	&flush_file_lines();
	&unlock_file($config{ 'sharetab_file' });
}

#check_cifs_config(sharename)
#return:found
sub check_cifs_config
{
	&foreign_require("samba", "samba-lib.pl");
	%econfig = &foreign_config("samba");
	&lock_file($econfig{'smb_conf'});
	@exps = &foreign_call("samba", "list_shares");
	my $found = 0;
	foreach $a (@exps) {
		if ($a eq $_[0])
		{
			$found = 1;
			break;
		}
	}
	&unlock_file($econfig{'smb_conf'});
	return $found;
}

#1st param is sharepath
#return: 1st param means exist(1) or not(0),the next are entry index array
sub check_nfs_config
{
	my $searchpath = $_[0];
	my @result;
	&foreign_require("exports", "exports-lib.pl");
	%econfig = &foreign_config("exports");
	&lock_file($econfig{'exports_file'});
	@exps = &foreign_call("exports", "list_exports");
	if (@exps)
	{
		@cl = grep {$_->{'dir'} eq $searchpath} @exps;
		if (@cl)
		{
			push(@result, 1);
			foreach $e (@cl)
			{
				push(@result, $e->{'index'});
			}
		}
		else
		{
			push(@result, 0);
		}

	}
	else
	{
		push(@result, 0);
	}

	&unlock_file($econfig{'exports_file'});
	return @result;

}

#check_ftp_config(sharepath)
#returns:chrootfound, pathfound, isanonymous, chrootstruct, pathstruct, anonymousstruct
sub check_ftp_config
{
	my ($chrootfound, $pathfound, $anonfound, $anon_other) = (0, 0, 0, 0);
	my ($chrootst, $pathst, $anonst) = (undef, undef, undef);
	&foreign_require("proftpd", "proftpd-lib.pl");
	%econfig = &foreign_config("proftpd");
	my $conf = &foreign_call("proftpd", "get_virtual_config", undef);
	my @chroots = &foreign_call("proftpd", "find_directive_struct", "DefaultRoot", $conf);
	if (@chroots)
	{
		foreach $d (@chroots) {
			if ($d->{'words'}->[0] eq $_[0])
			{
				$chrootfound = 1;
				$chrootst = $d;
				break;
			}
		}
	}

	my @dir = &foreign_call("proftpd", "find_directive_struct", "Directory", $conf);
	if (@dir)
	{
		foreach $d (@dir) {
			if ($d->{'words'}->[0] eq $_[0])
			{
				$pathfound = 1;
				$pathst = $d;
				break;
			}
		}
	}

	my @anon = &foreign_call("proftpd", "find_directive_struct", "Anonymous", $conf);
	if (@anon)
	{
		foreach $d (@anon) {
			$anonst = $d;
			if ($d->{'words'}->[0] eq $_[0])
			{
				$anonfound = 1;
				break;
			}
		}
	}
	if ((!$anonfound)&&defined($anonst))
	{
		if (@dir)
		{
			foreach $d (@dir) {
				if ($d->{'words'}->[0] eq $anonst->{'words'}->[0])
				{
					$anon_other = 1;
					break;
				}
			}
		}
	}
	return ($chrootfound, $pathfound, $anonfound, $chrootst, $pathst, $anonst, $anon_other);
}

#check_http_config(sharepname, sharepath)
#returns:namefound, pathfound, struct
sub check_http_config
{
	my ($namefd, $pathfd) = (0, 0);
	my $fdstruct = undef;
	my $droot;
	&foreign_require("apache", "apache-lib.pl");
	%econfig = &foreign_config("apache");
	#&foreign_call("apache", "lock_apache_files");
	my $conf = &foreign_call("apache", "get_virtual_config", undef);
	my @dir = &foreign_call("apache", "find_directive_struct", "DocumentRoot", $conf);
	if (@dir)
	{
		$droot = $dir[0]->{'words'}->[0];
		@dir = &foreign_call("apache", "find_directive_struct", "Directory", $conf);
		if (@dir)
		{
			foreach $d (@dir){
				$d->{'words'}->[0] =~ /^$droot\/(.*)$/;
				if (lc($1) eq lc($_[0]))
				{
					$namefd = 1;
					$fdstruct = $d;
					if (-l $d->{'words'}->[0])
					{
						my $res = readlink $d->{'words'}->[0];
						$pathfd = 1 if ($res eq $_[1]);
					}
					break;
				}
			}
		}
	}

	#&foreign_call("apache", "unlock_apache_files");
	return ($namefd, $pathfd, $droot, $fdstruct);
}

#input params:sharepath,sharename
#output params:1st param means sharepath exist(1) or not(0)
#		2nd param means sharename exist(1) or not(0)(not in the same line as sharepath)
sub check_sharetab
{
	&lock_file($config{'sharetab_file'});
	$file = &read_file_lines($config{'sharetab_file'});
	my ($foundpath, $foundname) = (0, 0);
	for($i=0; $i<@$file; $i++)
	{
    		$line = $file->[$i];
    		$line =~ s/\r|\n//g;
    		$line =~ s/#.*$//g;
    		$line =~ s/\/\/.*$//g;

    		if( $line )
    		{
			local $si = $i;

			while($line =~ /\\$/)
			{
				local $nl = $file->[++$i];
				$line =~ s/\\$//;
				$nl =~ s/^\s+//;
				$line .= $nl;
			}

        		local ( $path, $name, $stype, $comment ) = split( /:/, $line );
			if ($path eq $_[0])
			{
				$foundpath = 1;
				next;
			}

			if ($name eq $_[1])
			{
				$foundname = 1;
			}

    		}
	}
	&unlock_file($config{ 'sharetab_file' });
	@result = ($foundpath, $foundname);
}

sub delete_export_by_indexes
{
	my @exps = &foreign_call("exports", "list_exports");
	$a = $_[0];
	foreach $i (reverse(@$a))
	{
		$exp = $exps[$i];
		&foreign_call("exports", "delete_export", $exp);
	}
}

sub load_export_by_indexes
{
	$res = "";
	@exps = &foreign_call("exports", "list_exports");
	my $a = $_[0];
	foreach $i (@$a) {
		$exp = $exps[$i];
		next if ( !$exp->{'active'});
		local $h = $exp->{'host'};
		if ($h eq "=public")
		{
			$entrytxt = "$text{'webnfs'} ";
			$hosty = "2,";
		}
		elsif ($h =~ /^\@(.*)/)
		{
			$entrytxt = "$text{'netgroup'} ".$1." ";
			$hosty = "3,".$1;
		}
		elsif ($h =~ /^(\S+\/\S+)$/)
		{
			$entrytxt = "$text{'network'} ".$1." ";
			$hosty = "4,".$1;
		}
		elsif ($h eq ""||$h eq "*")
		{
			$entrytxt = "$text{'everyone'} ";
			$hosty = "0,";
		}
		else
		{
			$entrytxt = "$text{'hosts'} ".$h." ";
			$hosty = "1,".$h;
		}
		$hosty.= defined($exp->{'options'}->{'link_relative'})?",y":",n";
		if (defined($exp->{'options'}->{'ro'}))
		{
			$hosty.=",0";
			$entrytxt .=$text{'readonly'};
		}
		if (defined($exp->{'options'}->{'rw'}))
		{
			$hosty.=",1";
			$entrytxt .=$text{'readwrite'};
		}
		$hosty.= defined($exp->{'options'}->{'noaccess'})?",y":",n";
		$entrytxt .= defined($exp->{'options'}->{'noaccess'})?" $text{'denyaccess'}":"";
		$hosty.= defined ($exp->{'options'}->{'all_squash'})?",2":
				defined($exp->{'options'}->{'no_root_squash'})?",0":",1";

		$res .= ($entrytxt .":".$hosty.":");
	}
	return $res;
}

sub load_exports_by_indexes
{
	$res = "";
	@exps = &foreign_call("exports", "list_exports");
	my $a = $_[0];
	foreach $i (@$a) {
		$exp = $exps[$i];
		next if ( !$exp->{'active'});
		local $h = $exp->{'host'};
		if ($h eq "=public")
		{
#			$entrytxt = "$text{'webnfs'} ";
			$hosty = "2,";
		}
		elsif ($h =~ /^\@(.*)/)
		{
#			$entrytxt = "$text{'netgroup'} ".$1." ";
			$hosty = "3,".$1;
		}
		elsif ($h =~ /^(\S+\/\S+)$/)
		{
#			$entrytxt = "$text{'network'} ".$1." ";
			$hosty = "4,".$1;
		}
		elsif ($h eq ""||$h eq "*")
		{
#			$entrytxt = "$text{'everyone'} ";
			$hosty = "0,";
		}
		else
		{
#			$entrytxt = "$text{'hosts'} ".$h." ";
			$hosty = "1,".$h;
		}
#		$hosty.= defined($exp->{'options'}->{'link_relative'})?",y":",n";
		if (defined($exp->{'options'}->{'noaccess'}))
		{
			$hosty.=",2";
		}
		else
		{
			if (defined($exp->{'options'}->{'ro'}))
			{
				$hosty.=",0";
				#$entrytxt .=$text{'readonly'};
			}
			if (defined($exp->{'options'}->{'rw'}))
			{
				$hosty.=",1";
				#$entrytxt .=$text{'readwrite'};
			}
		}
#		$hosty.= defined($exp->{'options'}->{'noaccess'})?",y":",n";
#		$entrytxt .= defined($exp->{'options'}->{'noaccess'})?" $text{'denyaccess'}":"";
		$hosty.= defined ($exp->{'options'}->{'all_squash'})?",2":
				defined($exp->{'options'}->{'no_root_squash'})?",0":",1";

		$res .= ($hosty.":");
	}
	return $res;
}

sub split_input
{
	local @rv;
	local $str = $_[0];
	while($str =~ /^\s*(\S*"[^"]+"\S*)(.*)$/ || $str =~ /^\s*(\S+)(.*)$/) {
		push(@rv, $_[1].$1);
		$str = $2;
	}
	return @rv;

}

sub split_users
{
	return split(/\s*,\s*/, $_[0]);
}

sub get_mnt_root
{
	my $mntroot = "";
	open(STOR, "/etc/nas/voltab");
	while (<STOR>) {
		if (/^\s*volroot=\s*(\S*).*$/)
			{
				$mntroot = $1;
				break;
			}
	}
	close(STOR);
	return $mntroot;
}

sub get_volumes
{
	local @vols;
	open(STOR, "/etc/nas/voltab");
	my $n = 0;
	my $mntroot;
	while (<STOR>) {
		if (/^\s*volroot=\s*(\S*).*$/)
		{
			$mntroot = $1;
			next;
		}
		elsif (/^\s*#/)
		{
			next;
		}
		elsif (/^\s*(\S+)\s+\S*\s+(\S*).*$/)
		{
			$pname = $1;
			$mntstatus = $2;
			next if ($mntstatus !~ /^normal$/);
			$path = "$mntroot$pname";
			if (!(-d $path)) { next; }
			push(@vols, $pname);
		}

	}
	close(STOR);
	@vols = sort @vols;
	return @vols;
}

sub is_localgroup()
{
	my ($gname, @localgroup, $i, @line);

	$gname = $_[0];

	open(LOCALGROUP, $config{'localgroup_file'});
	@localgroup = <LOCALGROUP>;
	close(LOCALGROUP);

	for($i = 0; $i < @localgroup; $i++)
	{
		chomp($localgroup[$i]);
		if(($gname eq $localgroup[$i]) && ($gname))
		{
			return 1;
		}
	}
	return 0;
}

sub is_repeat_ftpdirroot()
{
	my (@proftpconf, $i, $gname, $dir, @line, $err_msg, $dirroot, $sname, $ex_gname, %sn_by_sdir);

	$gname = @_[0];
	$dir = $_[1];
	$err_msg = "";

	&foreign_require("proftpd", "proftpd-lib.pl");
	%econfig = &foreign_config("proftpd");

	open(PROFTPCONF, $econfig{'proftpd_conf'});
	@proftpconf = <PROFTPCONF>;
	close(PROFTPCONF);

	&get_sn_by_sdir(\%sn_by_sdir);



	for($i = 0; $i < @proftpconf; $i++)
	{
		$proftpconf[$i] =~ s/#.*$//;
		chomp($proftpconf[$i]);

		if($proftpconf[$i] =~ /^DefaultRoot/)
		{
			@line = split(/\s+/, $proftpconf[$i]);
			$ex_gname = pop @line;
			if($ex_gname eq $gname)
			{				
				$dirroot = $line[1];
				if($dirroot eq $dir)
				{
					next;
				}

				$sname = $sn_by_sdir{$dirroot};				
				$err_msg = &text("err_msg_ftproot_rep", $gname, $sname, $dirroot);
				return $err_msg;
			}
		}
	}
	return "";
	
}

#get sharename by sharedir
#get \%sn_by_sdir
#get_sn_by_sdir(\%sn_by_sdir)
sub get_sn_by_sdir()
{
	my (@sharetab, $i, @line, $sn_by_sdir);

	$sn_by_dir = $_[0];

	open(SHARETAB, $config{'sharetab_file'});
	@sharetab = <SHARETAB>;
	close(SHARETAB);

	for($i = 0; $i <@sharetab; $i++)
	{
		chomp($sharetab[$i]);
		$sharetab[$i] =~ s/#.*$//;

		if($sharetab[$i])
		{
			@line = split(":", $sharetab[$i]);
			$sn_by_dir->{$line[0]} = $line[1];
		}
	}
}


#check_input_num($input_num, $unit)
sub check_input_num()
{
	my ($input_num, $error_msg,$bignum, $smallnum, $str_length, $units);

	$input_num = @_[0];
	$units = @_[1];

	if($input_num =~ /^(\d+)(.*)/)
	{
		$bignum = $1;		
		if($2)
		{
			$smallnum = $2;
			if($smallnum =~ /^\.(\d+)$/)
			{
					$error_msg = "";

					$str_length = length($bignum);

					if($units eq "KB")
					{
						if($str_length > $config{'max_int_length'})
						{
							$error_msg = $text{'error_msg_input_num_tobig'};
						}						
					}
					
					if($units eq "MB")
					{
						if($str_length > 6)
						{
							$error_msg = $text{'error_msg_input_num_tobig'};
						}
					}
					
					if($units eq "GB")
					{
						if($str_length > 3)
						{
							$error_msg = $text{'error_msg_input_num_tobig'};
						}
					}
			}
			else
			{
				$error_msg = $text{"error_msg_input_not_num"};
			}
		}
		else
		{
			$error_msg = "";
			$str_length = length($input_num);

			if($units eq "KB")
			{
				if($str_length > $config{'max_int_length'})
				{
					$error_msg = $text{'error_msg_input_num_tobig'};
				}						
			}
			
			if($units eq "MB")
			{
				if($str_length > 6)
				{
					$error_msg = $text{'error_msg_input_num_tobig'};
				}
			}
			
			if($units eq "GB")
			{
				if($str_length > 3)
				{
					$error_msg = $text{'error_msg_input_num_tobig'};
				}
			}			
		}
	}
	else
	{
		$error_msg = $text{"error_msg_input_not_num"};
	}
	return $error_msg;
}

#check_input_not_integer(inputnum)
sub check_input_not_integer()
{
	my ($input_num, $error_msg,$bignum, $smallnum, $str_length);

	$input_num = @_[0];

	if($input_num =~ /^(\d+)$/)
	{
		$bignum = $1;
		$error_msg = "";
		$str_length = length($input_num);
		if($str_length > $config{'max_int_length'})
		{
			$error_msg = $text{'error_msg_input_num_tobig'};
		}
	}
	else
	{
		$error_msg = $text{"error_msg_input_not_num"};
	}
	return $error_msg;
}

#get_list_elemt(list, idx)
sub get_list_elemt()
{
        my ($list, @line, $idx, $i);
	$list = @_[0];
	$idx = @_[1];
	$unit_idx = @_[2];

	@line = split(',', $list);
	if($unit_idx)
	{
	        for($i = 0; $i < $line[$unit_idx]; $i++)
		{
	                $line[$idx] = $line[$idx] * 1024;
		}
	}
	return $line[$idx];
}

#sort_ftp_userlist(\@list, $sname)
sub sort_ftp_userlist()
{
        my ($list, $sname, %idx);
        $list = @_[0];
	$sname = @_[1];

	$idx{'usertype'} = 0;
	$idx{'name'} = 1;
	$idx{'accessmode'} = 2;
	$idx{'ftp_ub_short'} = 3;
	$idx{'ftp_db_short'} = 5;
	$idx{'ftp_sessonperuser_short'} = 7;
	if(($sname eq 'name'))
	{
 	        @$list = sort { &get_list_elemt($a, $idx{$sname}) cmp &get_list_elemt($b, $idx{$sname})} @$list;
	}
	if(($sname eq 'ftp_ub_short') || ($sname eq 'ftp_db_short'))
	{
	        @$list = sort { &get_list_elemt($a, $idx{$sname}, $idx{$sname}+1)  <=> &get_list_elemt($b, $idx{$sname}, $idx{$sname}+1)} @$list;
	}
	if(($sname eq 'ftp_sessonperuser_short') || ($sname eq 'accessmode') || ($sname eq usertype))
	{
	        @$list = sort { &get_list_elemt($a, $idx{$sname})  <=> &get_list_elemt($b, $idx{$sname})} @$list;
	}
}

#afp_save($afptrustusercache, $sharename, $sharepath, \%volcfg)
sub afp_save()
{
	my (@line, $i, @trustuser, %afpcfg, $shareline, $afptrustusercache, $sharename, $sharepath, $ptvolcfg);
	my (@allow_gp, @allow_usr, @rw_gp, @rw_usr, @ro_gp, @ro_usr, @deny_gp, @deny_usr);
	my ($err_msg);

	$afptrustusercache = @_[0];
	$sharename = @_[1];
	$sharepath = @_[2];
	$ptvolcfg = @_[3];

	@trustuser = split(":", $afptrustusercache);

	for($i = 0; $i < @trustuser; $i++)
	{
		@line = split(',' , $trustuser[$i]);

		next unless($line[1]);

		if($line[2] eq "ro")       #readonly item
		{
			if($line[0] == 1)
			{
				push @allow_gp, $line[1];   #group
				push @ro_gp, $line[1];
			}

			if($line[0] == 0)
			{
				push @allow_usr, $line[1];   #user
				push @ro_usr, $line[1];
			}			
		}

		if($line[2] eq "rw")       #readwrite item
		{
			if($line[0] == 1)
			{
				push @allow_gp, $line[1];   #group
				push @rw_gp, $line[1];
			}

			if($line[0] == 0)
			{
				push @allow_usr, $line[1];   #user
				push @rw_usr, $line[1];
			}			
		}

		if($line[2] eq "dy")       #deny item
		{
			if($line[0] == 1)
			{
				push @deny_gp, $line[1];   #group
			}

			if($line[0] == 0)
			{
				push @deny_usr, $line[1];   #user
			}			
		}
	}

	my @apvol_opions;

	$afpcfg{'share'} = $sharename;
	$afpcfg{'path'} = $sharepath;
	$afpcfg{'casefold_options'} = 'default';
	push @apvol_options, "noadouble";
	push @apvol_options, 'ro' if $ptvolcfg->{'ro'};
	$afpcfg{'options'} = join(',', @apvol_options);
	$afpcfg{'password'} = $ptvolcfg->{'password'} if $ptvolcfg->{'password'};
	
	#allow guest user for nobody is username
	push @allow_usr, 'nobody' if($ptvolcfg->{'allowguest'});

	#if administrator select userlist is empty, deny all
	if((@allow_gp == 0) && (@allow_usr == 0))
	{
		push @deny_gp, 'users';
	}

	$afpcfg{'allowgroups'} = join(' ' , @allow_gp);
	$afpcfg{'allowusers'} = join(' ' , @allow_usr);
	$afpcfg{'rogroups'} = join(' ' , @ro_gp);
	$afpcfg{'rousers'} = join(' ' , @ro_usr);
	$afpcfg{'rwgroups'} = join(' ' , @rw_gp);
	$afpcfg{'rwusers'} = join(' ' , @rw_usr);
	$afpcfg{'denygroups'} = join(' ' , @deny_gp);
	$afpcfg{'denyusers'} = join(' ' , @deny_usr);

	&foreign_require("netatalk", "netapple-lib.pl");
	$shareline = &foreign_call("netatalk", "ez_chg_line", \%afpcfg);
	$err_msg = &foreign_call("netatalk", "ez_save_afp", $shareline, $sharepath);

	return $err_msg;

#	print "<p>", $shareline;
#	&foreign_require("netatalk", "netapple-lib.pl");
#	&foreign_call("netatalk", "writeNewFileShare", \%afpcfg);
}

#get trust user cache list, and volume security config
#afp_get($sharename, $sharepath, \%volcfg)
sub afp_get()
{
	my ($sharename, $sharepath, $ptvolcfg, @trustuser);
	my (@allow_gp, @allow_usr, @rw_gp, @rw_usr, @ro_gp, @ro_usr, @deny_gp, @deny_usr);
	my ($allow, $deny, $rolist, $rwlist, %afshare, %uaccmod, %gaccmod, $k);

	$sharename = @_[0];
	$sharepath = @_[1];
	$ptvolcfg = @_[2];

	&foreign_require("netatalk", "netapple-lib.pl");

	&foreign_call("netatalk", "ez_get_afp", \%afshare, $sharepath);

#	foreach $k (keys %afshare)
#	{
#		print "<p>$k--->$afshare{$k}";
#	}

#	&foreign_call("netatalk", "open_afile");

#	$allow = &foreign_call("netatalk", "getAllow", $sharename);
	$allow = $afshare{'allow'};
	while( $allow =~ /([A-Za-z0-9@\$]+)/g)
	{
		if($1 =~ /^([@].*)/){
			if($1 =~ /([A-Za-z0-9\$]+)/){
				push(@allow_gp,$1);
			}
		}
		else{
			if($1 eq 'nobody')
			{
				$ptvolcfg->{'allowguest'} = 'yes';
			}
			push(@allow_usr,$1);
		}
	}
	
#	$deny = &foreign_call("netatalk", "getDeny", $sharename);
	$deny = $afshare{'deny'};
	while( $deny =~ /([A-Za-z0-9@\$]+)/g)
	{
		if($1 =~ /^([@].*)/){
			if($1 =~ /([A-Za-z0-9\$]+)/){
				push(@deny_gp,$1);
			}
		}
		else{
			push(@deny_usr,$1);
		}	
	}

#	$rolist = &foreign_call("netatalk", "getRolist", $sharename);
	$rolist = $afshare{'rolist'};
	while( $rolist =~ /([A-Za-z0-9@\$]+)/g)
	{
		if($1 =~ /^([@].*)/){
			if($1 =~ /([A-Za-z0-9\$]+)/){
				push(@ro_gp,$1);
			}
		}
		else{
			push(@ro_usr,$1);
		}	
	}

#	$rwlist = &foreign_call("netatalk", "getRwlist", $sharename);
	$rwlist = $afshare{'rwlist'};
	while( $rwlist =~ /([A-Za-z0-9@\$]+)/g)
	{
		if($1 =~ /^([@].*)/){
			if($1 =~ /([A-Za-z0-9\$]+)/){
				push(@rw_gp,$1);
			}
		}
		else{
			push(@rw_usr,$1);
		}
	}

	foreach $k (@ro_gp)
	{
		$gaccmod{$k} = "ro";
	}

	foreach $k (@rw_gp)
	{
		$gaccmod{$k} = "rw";
	}

	foreach $k (@deny_gp)
	{
		if($k eq 'users')
		{
			next;
		}
		$gaccmod{$k} = "dy";
	}

	foreach $k (@ro_usr)
	{
		$uaccmod{$k} = "ro";
	}

	foreach $k (@rw_usr)
	{
		$uaccmod{$k} = "rw";
	}

	foreach $k (@deny_usr)
	{
		$uaccmod{$k} = "dy";
	}

	foreach $k (keys %uaccmod)
	{
		push @trustuser, "0,".$k.",".$uaccmod{$k};
	}

	foreach $k (keys %gaccmod)
	{
		push @trustuser, "1,".$k.",".$gaccmod{$k};
	}

	$ptvolcfg->{'password'} = $afshare{'password'};
	$ptvolcfg->{'options'} = $afshare{'options'};

#	print "<p>", $ptvolcfg->{'options'}, $ptvolcfg->{'password'};

	return join(":", @trustuser);
}

#afp_del($sharepath)
sub afp_del()
{
	my ($sharepath);

	$sharepath = @_[0];

	&foreign_require("netatalk", "netapple-lib.pl");

	&foreign_call("netatalk", "ez_del_afp", $sharepath);

}

#sort_afp_uglist(\@afp_uglist, $sname)
#sname  --> sort name
sub sort_afp_uglist()
{
	 my ($list, $sname, %idx);

	 $list = @_[0];
	 $sname = @_[1];

	 $idx{'usertype'} = 0;
	 $idx{'name'} = 1;
	 $idx{'accessmode'} = 2;

	 if($sname eq "name")
	 {
 	        @$list = sort { &get_list_elemt($a, $idx{$sname}) cmp &get_list_elemt($b, $idx{$sname})} @$list;		 
	 }
}

#sort_cifs_uglist(\@cifs_uglist, $sname)
#sname  --> sort name
sub sort_cifs_uglist()
{
	 my ($list, $sname, %idx);

	 $list = @_[0];
	 $sname = @_[1];

	 $idx{'usertype'} = 0;
	 $idx{'name'} = 1;
	 $idx{'accessmode'} = 2;

	 if($sname eq "name")
	 {
 	        @$list = sort { &get_list_elemt($a, $idx{$sname}) cmp &get_list_elemt($b, $idx{$sname})} @$list;		 
	 }
}

1;
